package com.freight.order.serviceimpl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.freight.core.common.exception.FreightException;
import com.freight.core.common.redis.RedisTemplateHelper;
import com.freight.core.common.vo.SearchVo;
import com.freight.order.dao.OrderExtendDao;
import com.freight.order.dao.OrderOrderDao;
import com.freight.order.dao.OrderTrackDao;
import com.freight.order.entity.*;
import com.freight.order.mapper.OrderVoMapper;
import com.freight.order.service.IOrderVoService;
import com.freight.order.service.OrderGoodsService;
import com.freight.order.service.OrderOrderService;
import com.freight.order.service.OrderTrackService;
import com.freight.order.utils.CoordinateTransferUtils;
import com.freight.order.utils.DateUtils;
import com.freight.order.utils.JSONUtils;
import com.freight.order.vo.MobileTrackVo;
import com.freight.order.vo.OrderTrackVo;
import com.freight.user.dao.VehicleLicenseDao;
import com.freight.user.entity.VehicleLicense;
import com.freight.user.util.GpsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import java.util.*;

/**
 * 订单行车路径接口实现
 *
 * @author huyingtai
 */
@Slf4j
@Service
public class OrderTrackServiceImpl implements OrderTrackService {

    @Autowired
    private OrderTrackDao orderTrackDao;

    @Autowired
    private OrderOrderDao orderOrderDao;

    @Autowired
    private VehicleLicenseDao vehicleLicenseDao;

    @Autowired
    private OrderOrderService orderOrderService;

    @Autowired
    private OrderExtendDao orderExtendDao;

    @Autowired
    private OrderVoMapper orderVoMapper;

    @Autowired
    private OrderGoodsService orderGoodsService;

    @Autowired
    private IOrderVoService iOrderVoService;

    @Autowired
    private RedisTemplateHelper redisTemplate;

    private GpsUtil gpsUtil = new GpsUtil();

    @Override
    public OrderTrackDao getRepository() {
        return orderTrackDao;
    }

    @Override
    public Page<OrderTrack> findByCondition(OrderTrack orderTrack, SearchVo searchVo, Pageable pageable) {

        return orderTrackDao.findAll(new Specification<OrderTrack>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<OrderTrack> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

                // TODO 可添加你的其他搜索过滤条件 默认已有创建时间过滤
                Path<Date> createTimeField = root.get("createTime");

                List<Predicate> list = new ArrayList<>();

                // 创建时间
                if (StrUtil.isNotBlank(searchVo.getStartDate()) && StrUtil.isNotBlank(searchVo.getEndDate())) {
                    Date start = DateUtil.parse(searchVo.getStartDate());
                    Date end = DateUtil.parse(searchVo.getEndDate());
                    list.add(cb.between(createTimeField, start, DateUtil.endOfDay(end)));
                }

                Predicate[] arr = new Predicate[list.size()];
                cq.where(list.toArray(arr));
                return null;
            }
        }, pageable);
    }

    @Override
    public List<MobileTrackVo> getMobileTrack(Long orderId) {

        return orderVoMapper.getMobileTrack(orderId);
    }

    @Override
    public void updateMobileTrack() {
        List<OrderTrack> list = orderVoMapper.getOrderTrack();
        List<OrderTrack> lis = new ArrayList<>();
        for (OrderTrack orderTrack: list) {
            Map<String, Double> transform3Result = new CoordinateTransferUtils().wgs84ToGcj02(orderTrack.getLonF(), orderTrack.getLatF());
//            System.out.println("WGS84ToGCJ02 转换前经纬度(" + lon3 + "," + lat3 + ") 转换后经纬度(" + transform3Result.get("lon") + "," + transform3Result.get("lat") + ")");

            orderTrack.setLon(transform3Result.get("lon"));
            orderTrack.setLat(transform3Result.get("lat"));
            lis.add(orderTrack);
        }
        orderTrackDao.saveAll(lis);

    }

    /**
     * 查询车辆路径(经纬度信息)
     *
     * @param deviceids  车辆GPS识别号
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return JSON字符串，经纬度
     */
    @Override
    public List<OrderTrack> getLJ(Long orderId, String deviceids, String startTime, String endTime) {
        List<OrderTrack> tracks = new ArrayList<>();

        JSONObject data = new JSONObject();
        data.put("deviceid",deviceids);
        data.put("begintime",startTime);
        data.put("endtime",endTime);
        data.put("timezone",8);
        System.out.println(data);
        JSONObject requestJson = gpsUtil.gpsPost(data,"action=querytracks&",redisTemplate);
        if(requestJson!=null && requestJson.getInteger("status")==0){
            tracks.addAll(JSONUtils.getGJO(orderId, deviceids, requestJson));
        }else {
            throw new FreightException("车辆位置查询出错："+requestJson.getString("cause"));
        }
        return tracks;
    }

    public Map<String, Date> getOrderTime(Long orderId) {
        Map<String, Date> map = new HashMap<>();

        OrderOrder orderOrder = orderOrderService.get(orderId);
        if (orderOrder != null) {
            Date startTime = null, endTime = null;
            if (orderOrder.getOrderState() >= 2) { // 订单进行中
                OrderExtend orderExtend = orderExtendDao.findByOrderId(orderId);
                if (orderExtend != null) {
                        startTime = orderExtend.getLoadingTime();

                    if (orderExtend.getDischargeTime() != null) {
                        endTime = orderExtend.getDischargeTime();

                    } else {
                        endTime = new Date();
                    }
                }

                if (endTime.getTime() > new Date().getTime())
                    endTime = new Date();

                map.put("startTime", startTime);
                map.put("endTime", endTime);
            }
        }
        return map;
    }


    /**
     * @param orderID
     * @return
     */
    @Override
    public List<OrderTrackVo> getTracks(Long orderID) {

        OrderOrder orderOrder = orderOrderService.get(orderID);
        VehicleLicense vehicleLicense=vehicleLicenseDao.getOne(orderOrder.getVehicleId());
        OrderExtend orderExtend = orderExtendDao.findByOrderId(orderID);
        List<OrderTrackVo> orderTrackVos = new ArrayList<>();
        String tracks = null;

        if (orderOrder != null) {
            Integer orderState = orderOrder.getOrderState(); // 订单状态
            String carNum = vehicleLicense.getGpsEquipment(); // 车牌
            String startTime = null;
            String endTime = null;
            if (orderState < 2) {// 订单未开始 给开始结束地点
                return orderTrackVos;
            } else if (orderState == 2) { // 订单进行中
                List<OrderTrack> orderTracks = orderTrackDao.getOrderTrackByOrderIdOrderByGtmDesc(orderID);
                if (orderTracks.size() > 0) { // 有过查询
                    Date getTime = orderTracks.get(0).getGetTime(); // 取最近查询时间
                    startTime = DateUtils.dateFBD(getTime);
                    if (DateUtils.timeM(getTime) > 10) { // 小于10分钟不更新
                        endTime = DateUtils.dateFBD(new Date());
                    }
                } else { // 还没有查询过
                    Map<String, Date> map = getOrderTime(orderID);
                    if (map.get("startTime") != null) startTime = DateUtils.dateFBD(map.get("startTime"));
                    if (map.get("endTime") != null) endTime = DateUtils.dateFBD(map.get("endTime"));
                }

            } else { // 订单结束

                List<OrderTrack> orderTracks = orderTrackDao.getOrderTrackByOrderIdOrderByGtmDesc(orderID);

                    if (orderTracks.size() > 0) { // 有过查询
                        Date getTime = orderTracks.get(0).getGetTime(); // 取最近查询时间
                        Date updateTime = orderExtend.getDischargeTime();  // 获取订单到货时间

                        if (updateTime != null) {
                            if (getTime.getTime() < updateTime.getTime()) {
                                startTime = DateUtils.dateFBD(getTime);
                                endTime = DateUtils.dateFBD(updateTime);
                            }
                        }
                    } else { // 还没有查询过,使用订单中的发货时间和到货时间

                        startTime = DateUtils.dateFBD(orderExtend.getLoadingTime());

                        endTime = DateUtils.dateFBD(orderExtend.getDischargeTime());

                    }
                    orderExtendDao.save(orderExtend);
            }

            System.out.println("startTime : "+startTime + "   ：  " + endTime);
            if (startTime != null && endTime != null) {// 保存轨迹
                System.out.println(startTime + "   ：  " + endTime);
                List<OrderTrack> trackList = getLJ(orderID, carNum, startTime, endTime);
                if (trackList.size() > 0) {
                    orderTrackDao.saveAll(trackList);
                }
            }


            // 获取订单所有的轨迹信息
            List<OrderTrack> orderTracks1 = orderTrackDao.getOrderTrackByOrderIdOrderByGtmAsc(orderID);
            if (orderTracks1.size() > 0) {
//                tracks = JSONUtils.getTrackJSON(orderTracks1);
                for (int i = 0; i < orderTracks1.size(); i++) {
                    String time = orderTracks1.get(i).getGtm();
                    String gtm;
                    gtm=time;

                    OrderTrackVo orderTrackVo = new OrderTrackVo(orderTracks1.get(i).getLat(), orderTracks1.get(i).getLon(), orderTracks1.get(i).getSpd(),gtm,orderTracks1.get(i).getAgl(),orderTracks1.get(i).getMlg());
                    orderTrackVos.add(orderTrackVo);
                }
            }
        }else {
            if(orderOrder.getOrderState()>1){
                // 获取订单所有的轨迹信息
                List<OrderTrack> orderTracks1 = orderTrackDao.getOrderTrackByOrderIdOrderByGtmAsc(orderID);
                if (orderTracks1.size() > 0) {
//                tracks = JSONUtils.getTrackJSON(orderTracks1);
                    for (int i = 0; i < orderTracks1.size(); i++) {
                        String time = orderTracks1.get(i).getGtm();
                        String gtm;
                        if(time.length()==15){
                            String year=time.substring(0,4);
                            String month=time.substring(4,6);
                            String day=time.substring(6,8);
                            String hour=time.substring(9,11);
                            String minute=time.substring(11,13);
                            String second=time.substring(13,15);
                            gtm=year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second;
                        } else if(time.length()==23){
                            gtm=time.substring(0,19);
                        }else {
                            gtm=time;
                        }
                        OrderTrackVo orderTrackVo = new OrderTrackVo(orderTracks1.get(i).getLat(), orderTracks1.get(i).getLon(), orderTracks1.get(i).getSpd(),gtm,orderTracks1.get(i).getAgl(),orderTracks1.get(i).getMlg());
                        orderTrackVos.add(orderTrackVo);
                    }
                }
            }else {

            }

        }
        return orderTrackVos;
    }

    @Override
    public List<OrderTrackVo> getHistoryTracks(String gpsEquipment, String startTime, String endTime) {

        JSONObject data = new JSONObject();
        data.put("deviceid",gpsEquipment);
        data.put("begintime",startTime);
        data.put("endtime",endTime);
        data.put("timezone",8);
        System.out.println(data);
        JSONObject requestJson = gpsUtil.gpsPost(data,"action=querytracks&",redisTemplate);
        if(requestJson!=null && requestJson.getInteger("status")==0){
            return JSONUtils.getHistoryGJO(requestJson);
        }else {
            throw new FreightException("车辆位置查询出错："+requestJson.getString("cause"));
        }
    }

/*
    public List<OrderTrackVo> getTracks(Long orderID) {

        List<OrderTrackVo> orderTrackVos = new ArrayList<>();
        String tracks = null;
        OrderOrder orderOrder = orderOrderService.get(orderID);
        if (orderOrder != null) {
            Integer orderState = orderOrder.getOrderState(); // 订单状态
            String carNum = iOrderVoService.getOrderVoInfo(orderID).getDriverInfoVo().getDriverCode(); // 车牌
            String startTime = null;
            String endTime = null;
            if (orderState < 2) {// 订单未开始 给开始结束地点
                return orderTrackVos;
            } else if (orderState == 2) { // 订单进行中
                List<OrderTrack> orderTracks = orderTrackDao.getOrderTrackByOrderIdOrderByGtmDesc(orderID);
                if (orderTracks.size() > 0) { // 有过查询
                    Date getTime = orderTracks.get(0).getGetTime(); // 取最近查询时间
                    startTime = DateUtils.dateFBD(getTime);
                    if (DateUtils.timeM(getTime) > 10) { // 小于10分钟不更新
                        endTime = DateUtils.dateFBD(new Date());
                    }
                } else { // 还没有查询过
                    OrderExtend orderExtend = orderExtendDao.findByOrderId(orderID);
                    OrderGoods orderGoods = orderGoodsService.get(orderOrder.getGoodId());
                    if (orderExtend != null) {
                        if (orderGoods.getStartDate().getTime() > orderExtend.getCreateTime().getTime()) {
                            startTime = DateUtils.dateFBD(orderExtend.getCreateTime());
                        } else {
                            startTime = DateUtils.dateFBD(orderGoods.getStartDate());
                        }
                        if (orderGoods.getEndDate().getTime() < orderExtend.getUpdateTime().getTime()) {
                            endTime = DateUtils.dateFBD(orderExtend.getUpdateTime());
                        } else {
                            endTime = DateUtils.dateFBD(orderGoods.getEndDate());
                        }
                    } else {
                        startTime = DateUtils.dateFBD(orderGoods.getStartDate());
                        endTime = DateUtils.dateFBD(orderGoods.getEndDate());
                    }
                }

            } else { // 订单结束
                List<OrderTrack> orderTracks = orderTrackDao.getOrderTrackByOrderIdOrderByGtmDesc(orderID);
                OrderExtend orderExtend = orderExtendDao.findByOrderId(orderID);
                OrderGoods orderGoods = orderGoodsService.get(orderOrder.getGoodId());
                if (orderExtend != null) {
                    if (orderTracks.size() > 0) { // 有过查询
                        Date getTime = orderTracks.get(0).getGetTime(); // 取最近查询时间
                        Date updateTime = orderExtend.getUpdateTime();  // 获取订单到货时间

                        if (getTime.getTime() < updateTime.getTime()) {
                            startTime = DateUtils.dateFBD(getTime);
                            endTime = DateUtils.dateFBD(updateTime);
                        }
                    } else { // 还没有查询过,使用订单中的发货时间和到货时间
//                        startTime = DateUtils.dateFBD(orderExtend.getCreateTime());
//                        endTime = DateUtils.dateFBD(orderExtend.getUpdateTime());

                        if (orderGoods.getStartDate().getTime() > orderExtend.getCreateTime().getTime()) {
                            startTime = DateUtils.dateFBD(orderExtend.getCreateTime());
                        } else {
                            startTime = DateUtils.dateFBD(orderGoods.getStartDate());
                        }
                        if (orderGoods.getEndDate().getTime() < orderExtend.getUpdateTime().getTime()) {
                            endTime = DateUtils.dateFBD(orderExtend.getUpdateTime());
                        } else {
                            endTime = DateUtils.dateFBD(orderGoods.getEndDate());
                        }
                    }
                }
            }

            if (startTime != null && endTime != null) {// 保存轨迹
                System.out.println(startTime + "   ：  " + endTime);
                List<OrderTrack> trackList = getBDTracks(orderID, carNum, startTime, endTime);
                if (trackList.size() > 0) {
                    orderTrackDao.saveAll(trackList);
                }
            }

            // 获取订单所有的轨迹信息
            List<OrderTrack> orderTracks1 = orderTrackDao.getOrderTrackByOrderIdOrderByGtmAsc(orderID);
            if (orderTracks1.size() > 0) {
//                tracks = JSONUtils.getTrackJSON(orderTracks1);
                for (int i = 0; i < orderTracks1.size(); i++) {
                    OrderTrackVo orderTrackVo = new OrderTrackVo(orderTracks1.get(i).getLat(), orderTracks1.get(i).getLon(), orderTracks1.get(i).getSpd());
                    orderTrackVos.add(orderTrackVo);
                }
            }
        }
        return orderTrackVos;
    }
 */



}